#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int g_val = 10;

int func()
{
  int ret = fork();
  if (ret < 0){
    // error
    perror("fork error");
    return 0;
  }
  else if (ret == 0){
    // child
      printf("修改数据前：\n");
    int count = 0;
    while (1){
      printf("I am child,pid:%d %d:%p\n", getpid(), g_val, &g_val);
      sleep(1);
      count++;
      if (count == 3){
        g_val = 20;// 子进程对数据进行修改
        printf("修改数据后：\n");
      }
      }
       
  }
  else{
    // parent
    while (1){
      printf("I am parent:pid:%d %d:%p\n", getpid(), g_val, &g_val);
      sleep(1);
    }
  }
  return 0;
}

int init_val = 10;
int uninit_val;

int main(int argc, char* argv[], char* env[])
{
  const char* s = "abcd";
  printf( "code addr:%p\n", main);// 代码区
  printf("read only addr:%p\n", s);// 只读常量区
  printf("init addr:%p\n", &init_val);// 初始化数据
  printf("uninit addr:%p\n",&uninit_val);// 未初始化数据
  
  int* p1 = (int*) malloc(sizeof(int)*10);
  int* p2 = (int*) malloc(sizeof(int)*10);
  int* p3 = (int*) malloc(sizeof(int)*10);
  int* p4 = (int*) malloc(sizeof(int)*10);
  
  printf("heap addr:%p\n", p1);// 堆区
  printf("heap addr:%p\n", p2);// 堆区
  printf("heap addr:%p\n", p3);// 堆区
  printf("heap addr:%p\n", p4);// 堆区

  printf("stack addr:%p\n", &p1);// 栈区
  printf("stack addr:%p\n", &p2);// 栈区
  printf("stack addr:%p\n", &p3);// 栈区
  printf("stack addr:%p\n", &p4);// 栈区
  
  printf("command addr:%p\n", argv[0]);// 命令行参数

  printf("env addr:%p\n", env[0]);// 环境变量
   
  return 0;
}
